home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / Communication / receiptfilter / Source / receiptfilter.m < prev   
Encoding:
Text File  |  1994-01-06  |  5.4 KB  |  180 lines

  1. #import <stdio.h>
  2. #import <appkit/appkit.h>
  3. #import <sys/file.h>
  4. #import <syslog.h>
  5.  
  6.  
  7. /*
  8.  * receiptfilter
  9.  * A tool for keeping an eye on read receipts that Mail.app 
  10.  * automatically generates.
  11.  *
  12.  * Use:
  13.  *  Install this program as, say, /usr/local/lib/receiptfilter.
  14.  *  Start Mail.app.
  15.  *  In Mail.app's Preferences panel, choose "Expert" and change
  16.  *  the "Mailer:" field to "/usr/local/lib/receiptfilter".
  17.  *
  18.  * Now, every time Mail.app automatically tries to send a read receipt
  19.  * to someone letting them know that you've just read their message,
  20.  * an alert panel will pop up saying
  21.  *   "Send a receipt to shayman@Objectario.com?"
  22.  * and you can say "OK" or "No".
  23.  *
  24.  * How it Works:
  25.  * 
  26.  * This program is installed as the Mailer for Mail.app, meaning that
  27.  * all outgoing mail is handed to this program for delivery.  Normally
  28.  * your Mailer is "/usr/lib/sendmail".  If you change it to this program,
  29.  * it will check all the outgoing mail and if it finds a line like
  30.  * this
  31.  *    Subject: Read Receipt
  32.  * it will pop up the alert panel.  If you answer "No", this program
  33.  * merely exits and no receipt is sent.  
  34.  * If you answer "Yes", or if the original message didn't look like
  35.  * a read receipt, the message is given to /usr/lib/sendmail in the
  36.  * normal way and off it goes.
  37.  *
  38.  * Mail.app invokes the mailer program with the recipient or recipients
  39.  * on the command line, and the message itself on standard input.
  40.  * So this program copies the message from standard in to a temporary
  41.  * file, and watches for the "Subject: Read Receipt" line as it
  42.  * performs the copy.  When it comes time to send the message, this program
  43.  * arranges that the temporary file it created is standard input, and then
  44.  * executes "/usr/lib/sendmail" with the original argument list, so the
  45.  * message is delivered in the normal way.
  46.  *
  47.  * Downside:
  48.  *  - this program makes (and later deletes) a copy of every outgoing message
  49.  *    you send in /tmp, so it will take a tiny bit longer to deliver a
  50.  *    message, and some disk space will be used during delivery.
  51.  *  - if your normal Mail.app mailer program is something other than
  52.  *   /usr/lib/sendmail, you'll have to change this program to invoke
  53.  *   the correct "real" mailer.
  54.  *  - it might screw up if your mail message contains a single line longer
  55.  *    than 1024 characters, but I don't think Mail.app generates lines
  56.  *    like that.
  57.  *  - this program checks both the header of the message and the text itself
  58.  *    for the telltale "Subject: Read Receipt" line.  It should just
  59.  *    check the header, I guess.
  60.  *
  61.  * Use at your own risk.
  62.  *
  63.  * Future Enhancements:
  64.  *
  65.  * I suppose this could be enhanced in a few ways.  Make it configurable
  66.  * so that certain people (your friends) always get read receipts, others
  67.  * never get read receipts, etc etc.
  68.  *
  69.  * It could install itself nicely.  Maybe you run "receiptfilter -install"
  70.  * and it would set the Mail.app default automatically, and it would take
  71.  * note of what mailer you were previously using rather than assuming
  72.  * it was /usr/lib/sendmail.  
  73.  *
  74.  * Maybe a nice GUI for installation etc etc.
  75.  *
  76.  * Maybe this introductory comment could be shorter than the actual
  77.  * source code itself :-)
  78.  *
  79.  * Comments and suggestions are welcome.
  80.  * Steve Hayman
  81.  * shayman@Objectario.com
  82.  *
  83.  */
  84.  
  85. /*
  86.  * $Version$
  87.  * $Log:    receiptfilter.m,v $
  88.  * Revision 1.1  94/01/06  13:02:54  shayman
  89.  * Initial revision
  90.  * 
  91.  * Revision 1.1  94/01/06  13:01:34  shayman
  92.  * Initial revision
  93.  * 
  94.  */
  95.  
  96. main(argc, argv)
  97. int argc;
  98. char *argv[];
  99. {
  100.  
  101.     char *dest = argv[1];
  102.     int scratch;
  103.     FILE *f;
  104.     char tempfile[] = "/tmp/receiptfilter.XXXXXX";
  105.     char linebuf[1024];    // hope for no lines longer than this in the msg
  106.     BOOL isReceipt = NO;
  107.  
  108.     /*
  109.      * in case we need to report any errors, they'll be sent via
  110.      * syslog at priority "daemon.err", and should show up on the console.
  111.      */
  112.      
  113.     openlog("receiptfilter", LOG_CONS|LOG_PID, LOG_DAEMON);
  114.  
  115.     [Application new];
  116.     
  117.     /*
  118.      * Copy stdin to a temp file (and make sure it goes away
  119.      * when we're through with it); look for the telltale
  120.      * "Subject: Read Receipt\n" line.
  121.      */
  122.     scratch = mkstemp(tempfile);
  123.     unlink(tempfile);    
  124.  
  125.     
  126.     /*
  127.      * read lines from stdin; write to temp file.
  128.      */
  129.     while ( fgets(linebuf, sizeof(linebuf)-1, stdin) ) {
  130.         write(scratch, linebuf, strlen(linebuf));
  131.     
  132.     if ( strcmp(linebuf, "Subject: Read Receipt\n") == 0 ) 
  133.         isReceipt = YES;
  134.     
  135.     }
  136.     
  137.     /*
  138.      * Rewind scratch file; close stdin; dup scratch file.
  139.      * Effect is that the scratch file is our process's new stdin.
  140.      */
  141.     lseek( scratch, 0, L_SET );
  142.     close(0);
  143.     dup(scratch);
  144.     
  145.     /*
  146.      * If this message was a return receipt, give the user a chance
  147.      * to confirm whether it should be sent or not.
  148.      */
  149.     if ( isReceipt ) {
  150.     switch (
  151.         NXRunAlertPanel("Read Receipt", "Send a read receipt to %s?",
  152.             "OK", "No", NULL,dest) ) {
  153.     case NX_ALERTALTERNATE:    /* No */
  154.  
  155.         /*
  156.          * Exit immediately without calling sendmail.
  157.          */
  158.         exit(0);
  159.     case NX_ALERTDEFAULT:    /* OK */
  160.     default:
  161.         break;
  162.     }
  163.  
  164.     }
  165.     /*
  166.      * run sendmail, let it pick up our arguments and standard input.
  167.      *
  168.      * If your *original* Mail.app mailer was something other than
  169.      * /usr/lib/sendmail, change this line.
  170.      */
  171.     execv( "/usr/lib/sendmail", argv );
  172.  
  173.     /*
  174.      * shouldn't get here.
  175.      */
  176.     syslog(LOG_ERR, "Couldn't execute /usr/lib/sendmail.");
  177.     
  178.     exit(0);
  179. }
  180.